import React, { useEffect, useState } from "react";
import { View, StyleSheet } from "react-native";
import Cell from "./Cell";
import sudoku from "../utils/sudoku";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { Vibration } from 'react-native';

const SudokuBoard = ({ selectedNumber,setSelectedNumber,
    selectedNote,setSelectedNote,
    board,setBoard,
    loadSavedGame,
    selectedCell,handleCellSelection,
    level,
    wrongCells, setWrongCells,
    errorCount, setErrorCount,
    solution,setSolution,
    time,setTime,
    navigation}) => {
    const [isShow, setIsShow] = useState(true); //控制是否显示高亮行、列和块
    const [isAuto,setIsAuto]=useState(true);  //控制是否自动移除笔记
    const [isShakeOn,setIsShakeOn]=useState(true);

    const [winGameEasy, setWinGameEasy] = useState(0);
    const [winGameMid, setWinGameMid] = useState(0);
    const [winGameHard, setWinGameHard] = useState(0);

    const [shortestTimeEasy, setShortestTimeEasy] = useState(0);
    const [shortestTimeMid, setShortestTimeMid] = useState(0);
    const [shortestTimeHard, setShortestTimeHard] = useState(0);

    const [averageTimeEasy, setAverageTimeEasy] = useState(0);
    const [averageTimeMid, setAverageTimeMid] = useState(0);
    const [averageTimeHard, setAverageTimeHard] = useState(0);

    const [sumTimeEasy, setSumTimeEasy] = useState(0);
    const [sumTimeMid, setSumTimeMid] = useState(0);
    const [sumTimeHard, setSumTimeHard] = useState(0);

    const getBlock=(row,col)=>{
        const blockRowStart=Math.floor(row/3)*3;
        const blockColStart=Math.floor(col/3)*3;
        let blockCells=[];
        for(let r=blockRowStart;r<blockRowStart+3;r++){
            for(let c=blockColStart;c<blockColStart+3;c++){
                blockCells.push([r,c]);
            }
        }
        return blockCells;
    }

    useEffect(() => {
        const loadRecords=async()=>{
            try{
                const showWinGameEasy=await AsyncStorage.getItem('winGameEasy');
                const showWinGameMid=await AsyncStorage.getItem('winGameMid');
                const showWinGameHard=await AsyncStorage.getItem('winGameHard');
                const showShortestTimeEasy=await AsyncStorage.getItem('shortestTimeEasy');
                const showShortestTimeMid=await AsyncStorage.getItem('shortestTimeMid');
                const showShortestTimeHard=await AsyncStorage.getItem('shortestTimeHard');
                const showAverageTimeEasy=await AsyncStorage.getItem('averageTimeEasy');
                const showAverageTimeMid=await AsyncStorage.getItem('averageTimeMid');
                const showAverageTimeHard=await AsyncStorage.getItem('averageTimeHard');
                const showSumTimeEasy=await AsyncStorage.getItem('sumTimeEasy');
                const showSumTimeMid=await AsyncStorage.getItem('sumTimeMid');
                const showSumTimeHard=await AsyncStorage.getItem('sumTimeHard');
                if(showWinGameEasy!==null){
                    setWinGameEasy(JSON.parse(showWinGameEasy));
                }
                if(showWinGameMid!==null){
                    setWinGameMid(JSON.parse(showWinGameMid));
                }
                if(showWinGameHard!==null){
                    setWinGameHard(JSON.parse(showWinGameHard));
                }
                if(showShortestTimeEasy!==null){
                    setShortestTimeEasy(JSON.parse(showShortestTimeEasy));
                }
                if(showShortestTimeMid!==null){
                    setShortestTimeMid(JSON.parse(showShortestTimeMid));
                }
                if(showShortestTimeHard!==null){
                    setShortestTimeHard(JSON.parse(showShortestTimeHard));
                }
                if(showAverageTimeEasy!=null){
                    setAverageTimeEasy(JSON.parse(showAverageTimeEasy));
                }
                if(showAverageTimeMid!=null){
                    setAverageTimeMid(JSON.parse(showAverageTimeMid));
                }
                if(showAverageTimeHard!=null){
                    setAverageTimeHard(JSON.parse(showAverageTimeHard));
                }
                if(showSumTimeEasy!=null){
                    setSumTimeEasy(JSON.parse(showSumTimeEasy));
                }
                if(showSumTimeMid!=null){
                    setSumTimeMid(JSON.parse(showSumTimeMid));
                }
                if(showSumTimeHard!=null){
                    setSumTimeHard(JSON.parse(showSumTimeHard));
                }
            }catch(error){
                console.error("Error loading records:",error);
            }
        };
        loadRecords();
    }, []);

    const saveWinGameNumber=async()=>{
        try{
            if(level === 1) {
                await AsyncStorage.setItem("winGameEasy",JSON.stringify(winGameEasy+1));
                if(time < shortestTimeEasy || shortestTimeEasy === 0) {
                    await AsyncStorage.setItem("shortestTimeEasy",JSON.stringify(time));
                }
                await AsyncStorage.setItem("sumTimeEasy",JSON.stringify(sumTimeEasy+time));
                await AsyncStorage.setItem("averageTimeEasy",JSON.stringify(Math.round((sumTimeEasy+time)/(winGameEasy+1))));
            } else if(level === 2) {
                await AsyncStorage.setItem("winGameMid",JSON.stringify(winGameMid+1));
                if(time < shortestTimeMid || shortestTimeMid === 0) {
                    await AsyncStorage.setItem("shortestTimeMid",JSON.stringify(time));
                }
                await AsyncStorage.setItem("sumTimeMid",JSON.stringify(sumTimeMid+time));
                await AsyncStorage.setItem("averageTimeMid",JSON.stringify(Math.round((sumTimeMid+time)/(winGameMid+1))));
            } else {
                await AsyncStorage.setItem("winGameHard",JSON.stringify(winGameHard+1));
                if(time < shortestTimeHard || shortestTimeHard === 0) {
                    await AsyncStorage.setItem("shortestTimeHard",JSON.stringify(time));
                }
                await AsyncStorage.setItem("sumTimeHard",JSON.stringify(sumTimeHard+time));
                await AsyncStorage.setItem("averageTimeHard",JSON.stringify(Math.round((sumTimeHard+time)/(winGameHard+1))));
            }
        }catch(error){
            console.error("Error saving winGame:",error);
        }
    }

    //加载用户设置
    useEffect(()=>{
        const loadSettings=async()=>{
            try{
                const showSetting=await AsyncStorage.getItem('isShow');
                if(showSetting!==null){
                    setIsShow(JSON.parse(showSetting));
                }
                const autoSetting=await AsyncStorage.getItem('isAuto');
                if(autoSetting!==null){
                    setIsAuto(JSON.parse(autoSetting));
                }
                const showIsShakeOn=await AsyncStorage.getItem('isShakeOn');
                if(showIsShakeOn!==null){
                    setIsShakeOn(JSON.parse(showIsShakeOn));
                }
            }catch(error){
                console.error("Error loading settings:",error);
            }
        }
        loadSettings();
    },[]);

    //加载保存的游戏或生成新游戏
    useEffect(() => {
        if (loadSavedGame) {
            const loadSaveGame = async () => {
                try {
                    const savedGameState = await AsyncStorage.getItem('gameState');
                    if (savedGameState) {
                        const gameState = JSON.parse(savedGameState);
                        setBoard(gameState.board);
                        setErrorCount(gameState.errorCount || 0);
                        setSolution(gameState.solution);
                        await AsyncStorage.removeItem('gameState');
                    }
                } catch (error) {
                    console.error("Error loading saved game:", error);
                }
            };
            loadSaveGame();
        } else {
            console.log("level: "+level);
            let puzzle = sudoku.makepuzzle();
            let rate = sudoku.ratepuzzle(puzzle,level);
            puzzle = rate;

            if(puzzle != null){
                let temp = Array(9).fill().map(() => Array(9).fill({ value: null, noteValue: null, isFixed: false,isUserInput: false,isError:false }));
                let k = 0;
                for (let i = 0; i < 9; i++) {
                    for (let j = 0; j < 9; j++) {
                        temp[i][j] = puzzle[k] === null ? { value: null, noteValue: null, isFixed: false,isUserInput: false,isError:false  } : { value: puzzle[k] + 1, noteValue: null, isFixed: true ,isUserInput: false,isError:false };
                        k++;
                    }
                }
                setBoard(temp);
                setSolution(sudoku.solvepuzzle(puzzle));
            }
        }
    }, [loadSavedGame, setBoard]);

    const checkCompletion=()=>{
        for(let i=0;i<9;i++){
            for(let j=0;j<9;j++){
                if(board[i][j].value==null||board[i][j].isError){
                    return;
                }
            }
        }
        saveWinGameNumber();
        if(isShakeOn){
            Vibration.vibrate(500);
        }
        navigation.navigate("Game_success");
    }

    //处理单元格选择和数字输入
    useEffect(() => {
        if (selectedNumber && selectedCell && solution) {
            const newBoard = [...board];
            const { row, col } = selectedCell;
            if(!newBoard[row][col].isFixed) {
                newBoard[row][col].value = selectedNumber;
                
                const correctNumber = solution[row * 9 + col] + 1;
                if(selectedNumber !== correctNumber) {
                    setErrorCount(errorCount+1);
                    const wrongPositions = [];
                    for(let i = 0; i < 9; i++) {
                        if(newBoard[row][i].value === selectedNumber) {
                            wrongPositions.push({rowkey: row, colkey: i});
                        }
                    }
                    for(let i = 0; i < 9; i++) {
                        if(newBoard[i][col].value === selectedNumber) {
                            wrongPositions.push({rowkey: i, colkey: col});
                        }
                    }

                const blockStartRow = Math.floor(row/3) * 3;
                const blockStartCol = Math.floor(col/3) * 3;
                
                for(let i = blockStartRow; i < blockStartRow + 3; i++) {
                    for(let j = blockStartCol; j < blockStartCol + 3; j++) {
                        if(newBoard[i][j].value === selectedNumber) {
                            wrongPositions.push({rowkey: i, colkey: j});
                        }
                    }
                }
                
                newBoard[row][col].isError = true;
                setWrongCells(wrongPositions);

                if (errorCount>=3) {
                    if(isShakeOn){
                        Vibration.vibrate(500);
                    }
                    navigation.navigate("Game_failure");
                    return;
                }

                } else {
                    newBoard[row][col].isFixed = true;
                    newBoard[row][col].isUserInput = true;
                    newBoard[row][col].isError = false;
                    setWrongCells([]);
                }
                newBoard[row][col].noteValue=[];
                setBoard(newBoard);

                if(selectedNumber === correctNumber) {
                    checkCompletion();
                }
            }
            if(isAuto&&!newBoard[row][col].isError){
                const removeNotes=(num)=>{
                    const blockCells=getBlock(row,col);
                    for(let i=0;i<9;i++){
                        if(i!==col){
                            const cell=newBoard[row][i];
                            if(cell.noteValue&&cell.noteValue.includes(num)){
                                cell.noteValue=cell.noteValue.filter(note =>note!==num) || [];
                            }
                        }
                    }
                    for(let i=0;i<9;i++){
                        if(i!==row){
                            const cell=newBoard[i][col];
                            if(cell.noteValue&&cell.noteValue.includes(num)){
                                cell.noteValue=cell.noteValue.filter(note =>note!==num) || [];
                            }
                        }
                    }
                    blockCells.forEach(([r,c])=>{
                        if(r!==row||c!==col){
                            const cell=newBoard[r][c];
                            if(cell.noteValue&&cell.noteValue.includes(num)){
                                cell.noteValue=cell.noteValue.filter(note=>note!==num)||[];
                            }
                        }
                    })
                }
                removeNotes(selectedNumber);
                setBoard(newBoard);
            }
            setSelectedNumber(null);
        }
    }, [selectedNumber, selectedCell]);
    

    //处理笔记输入
    useEffect(()=>{
        if(selectedNote&&selectedCell){
            const newBoard=[...board];
            const {row,col}=selectedCell;
            if(!newBoard[row][col].isFixed){
                const notes = newBoard[row][col].noteValue || [];
                if (!notes.includes(selectedNote)) {
                    notes.push(selectedNote); 
                }
                newBoard[row][col].noteValue = notes;
                setBoard(newBoard);
            }
        }
        setSelectedNote(null);
    },[selectedNote,board,setSelectedNote])



    //获取高亮信息
    const getHighlightInfo=()=>{
        if (!selectedCell) return { row: [], col: [], block: [] };
        const {row,col}=selectedCell;
        const block=getBlock(row,col);
        const rowHighlight=isShow?[row]:[];
        const colHightlight=isShow?[col]:[];
        const blockHightlight=isShow?block:[];
        return {row:rowHighlight,col:colHightlight,block:blockHightlight};
    }

    return (
        <View style={styles.board}>
            {board.map((row, rowIndex) => (
                <View key={rowIndex} style={styles.row}>
                    {row.map((cell, colIndex) => (
                        <Cell
                            key={`${rowIndex}-${colIndex}`}
                            rowkey={rowIndex}
                            colkey={colIndex}
                            value={cell}
                            onSelectedCell={handleCellSelection}
                            selected={selectedCell && selectedCell.row === rowIndex && selectedCell.col === colIndex}
                            highlightAre={getHighlightInfo()}
                            wrongCell={wrongCells}
                        />
                    ))}
                </View>
            ))}
        </View>
    );
};

const styles = StyleSheet.create({
    board: {
        width: 335,
        height: 335,
        backgroundColor: "#f5f5f5",
        flexDirection: "column",
    },
    row: {
        flexDirection: "row",
    },
});

export default SudokuBoard;
